package is1;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;


public class CalculadoraREST extends CalculadoraImpuestos 
{
	private int versionCalculo = 2;
	
	@Override
	public float calcularImpuestosLinea(LinVenta lineaVenta)
	{
		float calculoImpuesto = 0.0f;

		if (versionCalculo == 1)
		{
			// Obtener el codigo correcto que acepta el sistema REST
			String [] codigoParticion = lineaVenta.getProducto().getCodigo().split("\\s+");
			String codigoProducto = codigoParticion[codigoParticion.length-1];				
			
			ArrayList<Impuesto> impuestos = impuestosProducto(codigoProducto);
			for (Impuesto imp: impuestos)
			{
				calculoImpuesto += lineaVenta.getPrecioTotal() * (imp.porcentaje / 100.0f);
			}
		}
		else if (versionCalculo == 2)
		{
			// Obtener el codigo correcto que acepta el sistema REST
			String [] codigoParticion = lineaVenta.getProducto().getCodigo().split("\\s+");
			String codigoProducto = codigoParticion[codigoParticion.length-1];				
			
			float acumPorcentaje = 1.0f;
			ArrayList<Impuesto> impuestos = impuestosProducto(codigoProducto);
			for (Impuesto imp: impuestos)
			{
				acumPorcentaje += (imp.porcentaje / 100.0f);
			}
			
			float c = lineaVenta.getPrecioTotal() / acumPorcentaje;
			calculoImpuesto = lineaVenta.getPrecioTotal() - c;
		}
		
		return calculoImpuesto;
	}
	
	@Override
	public void calcularImpuestos(Venta venta) 
	{
		float impuestosTotalVenta = 0.0f;
		
		for (LinVenta lineaVenta: venta.getLineas())
		{
			impuestosTotalVenta += calcularImpuestosLinea(lineaVenta);
		}
		
		venta.setImpuestos(impuestosTotalVenta);
	}

	@Override
	public ArrayList<Impuesto> impuestosProducto(String codProducto) 
	{
		ArrayList<Impuesto> impuestos = new ArrayList<Impuesto>();

		String strXML = "";
		try 
		{
			// Hacer la peticion a la URL con el producto
			URL url = new URL(URL + "?producto=" + codProducto);
			URLConnection con = url.openConnection();
			BufferedReader buff = new BufferedReader(new InputStreamReader(con.getInputStream()));
			
			// Leer el xml de la peticion
			String nextLine = buff.readLine();
			while(nextLine != null)
			{
				strXML += nextLine + "\n";
				nextLine = buff.readLine();
			}
		}
		catch (Exception e)
		{
			System.out.println("Problema con la conexion URL o el acceso a los datos en la conexion");
		}
		
		try 
		{
			DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		    InputSource is = new InputSource();
		    is.setCharacterStream(new StringReader(strXML));
	        
		    Document doc = db.parse(is);
	        doc.getDocumentElement().normalize();
			Element elem = doc.getDocumentElement();
			// Eliminar los nodos #text del DOM si existen.
			for (int i = 0; i < elem.getChildNodes().getLength(); i++)
			{
				Node hijo = elem.getChildNodes().item(i);

				if (hijo.getNodeName().equals("#text"))
				{
					elem.removeChild(hijo);
					i--;
				}
			}
			
			NodeList hijos = elem.getChildNodes();	
			for (int i = 0; i < hijos.getLength(); i++)
			{
				Impuesto imp;
				
				if (hijos.item(i).getNodeName().equals("iva"))
				{
					imp = new ImpuestoRESTIva(Float.parseFloat( hijos.item(i).getTextContent() ));
					impuestos.add(imp);
				} 
				else if (hijos.item(i).getNodeName().equals("especial"))
				{
					imp = new ImpuestoRESTEspecial(Float.parseFloat( hijos.item(i).getTextContent() ), 
							hijos.item(i).getAttributes().getNamedItem("concepto").getTextContent());
					impuestos.add(imp);
				}
			}
		} 
		catch (ParserConfigurationException e) 
		{
			System.err.println("Error al crear DocumentBuilder en CalculadoraREST.impuestosProducto()");
		}
		catch (SAXException e) 
		{
			System.err.println("Error al parsear el xml en CalculadoraREST.impuestosProducto()");
		} 
		catch (IOException e) 
		{
			System.err.println("Error de entrada y salida en CalculadoraREST.impuestosProducto()");
		}
		
		return impuestos;
	}
	
	
	public static void setInstance(CalculadoraImpuestos ci)
	{
		calculadoraImpuestos = ci;
	}
	
	public static CalculadoraImpuestos getInstance()
	{
		if (calculadoraImpuestos == null)
		{
			calculadoraImpuestos = new CalculadoraREST();
		}
		return calculadoraImpuestos;
	}	
}
